import { BaseConverter } from './BaseConverter.js';
import { InvalidSchemaError } from './errors.js';
import { copyKeyIfDefined } from './utils.js';
export class SecurityConverter extends BaseConverter {
    constructor(securityRequirements, securitySchemes, safeParse = false) {
        super(safeParse);
        this.securityRequirements = securityRequirements;
        this.securitySchemes = securitySchemes;
        this.safeParse = safeParse;
    }
    convert() {
        if (this.securityRequirements === undefined || this.securityRequirements.length === 0) {
            return [];
        }
        if (this.securitySchemes === undefined) {
            this.handleNewError(InvalidSchemaError, ['#', 'components'], 'securitySchemes not defined');
            return [];
        }
        // TODO(ronan): make this work for camel-case as well
        return this.securityRequirements.map((security) => {
            const title = Object.keys(security)
                .map((securityName) => securityName.replace(/[_-]/g, ' '))
                .join(' & ');
            const parameterSections = {
                query: {},
                header: {},
                cookie: {},
            };
            Object.keys(security).forEach((securityName) => {
                var _a;
                const securityScheme = (_a = this.securitySchemes) === null || _a === void 0 ? void 0 : _a[securityName];
                if (securityScheme === undefined) {
                    this.handleNewError(InvalidSchemaError, ['#', 'components', 'securitySchemes'], `security scheme not defined: '${securityName}'`);
                    return;
                }
                this.addSecurityParameters(securityName, securityScheme, parameterSections);
            });
            return {
                title,
                parameters: parameterSections,
            };
        });
    }
    addSecurityParameters(securityName, securityScheme, parameterSections) {
        switch (securityScheme.type) {
            case 'apiKey': {
                if (!['header', 'query', 'cookie'].includes(securityScheme.in)) {
                    this.handleNewError(InvalidSchemaError, ['#', 'components', 'securitySchemes', securityName], `invalid security scheme location provided: '${securityScheme.in}'`);
                    return;
                }
                const paramGroup = securityScheme.in;
                const schema = { type: 'apiKey' };
                copyKeyIfDefined('description', securityScheme, schema);
                parameterSections[paramGroup][securityScheme.name] = schema;
                return;
            }
            case 'http': {
                const scheme = securityScheme.scheme;
                if (scheme === 'basic' || scheme === 'bearer') {
                    const schema = {
                        type: 'http',
                        scheme,
                    };
                    copyKeyIfDefined('description', securityScheme, schema);
                    parameterSections.header['Authorization'] = schema;
                }
                else {
                    this.handleNewError(InvalidSchemaError, ['#', 'components', 'securitySchemes', securityName], `encountered unknown HTTP security scheme: '${securityScheme.scheme}'`);
                    return;
                }
                return;
            }
            case 'oauth2': {
                const schema = { type: 'oauth2' };
                copyKeyIfDefined('description', securityScheme, schema);
                parameterSections.header['Authorization'] = schema;
                return;
            }
            case 'openIdConnect': {
                return;
            }
        }
    }
    static convert(securityRequirements, securitySchemes, safeParse) {
        return new SecurityConverter(securityRequirements, securitySchemes, safeParse).convert();
    }
}
